import config from './config';
import request from './request';
import storage from './storage';
import { color } from './theme';
import chartData from './chartData';
import encryption from './encryption'; // 加密
import getLocalIP from './getLocalIP';
import lodash from 'lodash';

/**
 * @param   {String}
 * @return  {String}
 */
const queryURL = name => {
  let reg = new RegExp(`(^|&)${name}=([^&]*)(&|$)`, 'i');
  let r = window.location.search.substr(1).match(reg);
  if (r != null) return decodeURI(r[2]);
  return null;
};

/**
 * 数组内查询
 * @param   {array}      array
 * @param   {String}    id
 * @param   {String}    keyAlias
 * @return  {Array}
 */
const queryArray = (array, key, keyAlias = 'key') => {
  if (!(array instanceof Array)) {
    return null;
  }
  const item = array.filter(_ => _[keyAlias] === key);
  if (item.length) {
    return item[0];
  }
  return null;
};

/**
 * 数组格式转树状结构
 * @param   {array}     array
 * @param   {String}    id
 * @param   {String}    pid
 * @param   {String}    children
 * @return  {Array}
 */
const arrayToTree = (array = [], id = 'id', pid = 'pid', children = 'children') => {
  if (!Array.isArray(array)) {
    return [];
  }
  let data = lodash.cloneDeep(array);
  let result = [];
  let hash = {};
  data.forEach((item, index) => {
    hash[data[index][id]] = data[index];
  });

  data.forEach(item => {
    let hashVP = hash[item[pid]];
    if (hashVP) {
      !hashVP[children] && (hashVP[children] = []);
      hashVP[children].push(item);
    } else {
      result.push(item);
    }
  });
  return result;
};

/**
 * json 转换成 urlencoded
 * @ param {object} data
 */
const jsonToUrlencoded = data => {
  return Object.keys(data)
    .map(key => {
      return `${encodeURIComponent(key)}=${encodeURIComponent(data[key])}`;
    })
    .join('&');
};

/**
 *  替换对象属性名称
 * @ param {array} data
 */
const changeKeyNames = (arry, namesMap) => {
  let arryData = [];
  if (!Array.isArray(arry) || arry.length === 0) {
    return arryData;
  }
  arryData = arry.map(item => {
    const temp = { ...item };
    Object.keys(namesMap).forEach(key => {
      temp[key] = temp[namesMap[key]];
    });
    return temp;
  });
  return arryData;
};

/** 表单正则校验规则
 *
 */
const regex = {
  phone: '^1[34578]\\d{9}$',
  loginname: /^[a-zA-Z]{1}([a-zA-Z0-9]|[._]){3,14}$/,
  urlPrefix: '^(http://|https://)',
  ip: /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/,
};

/**
 *  下载文件
 */
const fileDownLoad = fileUrl => {
  let elemIF = document.getElementById('fileDownLoad');
  if (!elemIF) {
    elemIF = document.createElement('iframe');
    elemIF.id = 'fileDownLoad';
    elemIF.src = fileUrl;
    elemIF.style.display = 'none';
    document.body.appendChild(elemIF);
  } else {
    elemIF.src = '';
    elemIF.src = fileUrl;
  }
};

/**
 * 用户页面权限
 * @param {String | Number} limitCode 页面权限码
 * @param {String} type 权限类型
 */
const isLimited = (limitCode, type) => {
  limitCode = Number(limitCode);
  let result;
  switch (type) {
    case 'create':
      result = limitCode > 0 && limitCode < 6;
      break;
    case 'update':
      result = limitCode > 0 && limitCode < 4;
      break;
    case 'execute':
      result = limitCode === 1 || limitCode === 4 || limitCode === 2 || limitCode === 6;
      break;
    case 'delete':
      result = limitCode === 1;
      break;
    default:
      result = false;
      break;
  }
  return result;
};

// 等待几秒
const sleep = delay => {
  const _time = new Date().getTime();
  while (_time + delay * 1000 > new Date().getTime()) {}
};

/** 计算字符串的
 *  @param str string 要计算长度字符串
 *  */
const getStrLength = str => {
  return str.replace(/[\u0391-\uFFE5]/g, 'aa').length; //先把中文替换成两个字节的英文，再计算长度
};

/**
 * 格式化数字 1000 -> 1k
 * @param {number} num
 * @param {number} digits
 * @returns
 */
function numberFormatter(num = 0, digits = 2) {
  const si = [
    { value: 1, symbol: '' },
    { value: 1e3, symbol: 'K' },
    { value: 1e6, symbol: 'M' },
    { value: 1e9, symbol: 'G' },
    { value: 1e12, symbol: 'T' },
    { value: 1e15, symbol: 'P' },
    { value: 1e18, symbol: 'E' },
  ];
  const rx = /\.0+$|(\.[0-9]*[1-9])0+$/;
  let i;
  for (i = si.length - 1; i > 0; i--) {
    if (num >= si[i].value) {
      break;
    }
  }
  return (num / si[i].value).toFixed(digits).replace(rx, '$1') + si[i].symbol;
}

export {
  config,
  request,
  color,
  queryURL,
  queryArray,
  arrayToTree,
  jsonToUrlencoded,
  chartData,
  changeKeyNames,
  regex,
  fileDownLoad,
  isLimited,
  storage,
  sleep,
  getStrLength,
  encryption,
  getLocalIP,
  numberFormatter,
};

// 日期格式化
Date.prototype.format = function(format) {
  let resulet = format;
  const o = {
    'M+': this.getMonth() + 1,
    'd+': this.getDate(),
    'h+': this.getHours(),
    'H+': this.getHours(),
    'm+': this.getMinutes(),
    's+': this.getSeconds(),
    'q+': Math.floor((this.getMonth() + 3) / 3),
    S: this.getMilliseconds(),
  };
  if (/(y+)/.test(resulet)) {
    resulet = resulet.replace(RegExp.$1, `${this.getFullYear()}`.substr(4 - RegExp.$1.length));
  }
  for (const k in o) {
    if (new RegExp(`(${k})`).test(resulet)) {
      resulet = resulet.replace(
        RegExp.$1,
        RegExp.$1.length === 1 ? o[k] : `00${o[k]}`.substr(`${o[k]}`.length)
      );
    }
  }
  return resulet;
};
